<template>
    <div>
        <generate-code-enum ref="enum" :app="app" :clazz="clazz" v-if="clazz instanceof EnumClass"/>
        <generate-code-value ref="value" :app="app" :clazz="clazz" v-else-if="clazz instanceof ValueClass"/>
        <generate-code-plain ref="plain" :app="app" :clazz="clazz" v-else-if="clazz instanceof PlainClass"/>
        <el-tabs type="border-card" v-model="type" class="mb-0" v-else-if="clazz instanceof EntityClass">
            <el-tab-pane :label="typeItem.caption" v-for="typeItem of typeItems" :key="typeItem.name"
                :name="typeItem.name">
                <generate-code-entity ref="entity" :app="app" :clazz="clazz" v-if="typeItem.name === 'entity'"/>
                <generate-code-sql ref="sql" :app="app" :clazz="clazz" v-else-if="typeItem.name === 'sql'"/>
                <generate-code-jpa ref="jpa" :app="app" :clazz="clazz" v-else-if="typeItem.name === 'jpa'"/>
                <generate-code-querying ref="querying" :app="app" :clazz="clazz"
                    v-else-if="typeItem.name === 'querying'"/>
                <generate-code-repo ref="repo" :app="app" :clazz="clazz" v-else-if="typeItem.name === 'repo'"/>
                <generate-code-command ref="command" :app="app" :clazz="clazz" v-else-if="typeItem.name === 'command'"/>
                <generate-code-service ref="service" :app="app" :clazz="clazz" v-else-if="typeItem.name === 'service'"/>
                <generate-code-controller ref="controller" :app="app" :clazz="clazz"
                    v-else-if="typeItem.name === 'controller'"/>
            </el-tab-pane>
        </el-tabs>
    </div>
</template>

<script>
import ModelingApp from '@/logic/modeling/entity/ModelingApp.js';
import ModelingClass from '@/logic/modeling/entity/ModelingClass.js';
import EnumClass from '@/logic/modeling/entity/EnumClass.js';
import ValueClass from '@/logic/modeling/entity/ValueClass.js';
import PlainClass from '@/logic/modeling/entity/PlainClass.js';
import EntityClass from '@/logic/modeling/entity/EntityClass.js';
import GenerateUtil from '@/logic/modeling/util/generate.js';

import 'highlight.js/styles/idea.css';
import GenerateCodeEnum from './generate-code-enum.vue';
import GenerateCodeValue from './generate-code-value.vue';
import GenerateCodePlain from './generate-code-plain.vue';
import GenerateCodeEntity from './generate-code-entity.vue';
import GenerateCodeSql from './generate-code-sql.vue';
import GenerateCodeJpa from './generate-code-jpa.vue';
import GenerateCodeQuerying from './generate-code-querying.vue';
import GenerateCodeRepo from './generate-code-repo.vue';
import GenerateCodeCommand from './generate-code-command.vue';
import GenerateCodeService from './generate-code-service.vue';
import GenerateCodeController from './generate-code-controller.vue';
import save from './generate-code-save.vue';

export default {
    components: {
        GenerateCodeEnum,
        GenerateCodeValue,
        GenerateCodePlain,
        GenerateCodeEntity,
        GenerateCodeSql,
        GenerateCodeJpa,
        GenerateCodeQuerying,
        GenerateCodeRepo,
        GenerateCodeCommand,
        GenerateCodeService,
        GenerateCodeController,
    },
    props: {
        app: {
            type: ModelingApp,
            required: true,
        },
        clazz: {
            type: ModelingClass,
            required: true,
        },
        after: Function,
    },
    data() {
        return {
            type: 'entity',
        };
    },
    computed: {
        EnumClass() {
            return EnumClass;
        },
        ValueClass() {
            return ValueClass;
        },
        PlainClass() {
            return PlainClass;
        },
        EntityClass() {
            return EntityClass;
        },
        typeItems() {
            return GenerateUtil.entityCodeTypeItems;
        },
    },
    mounted() {
    },
    methods: {
        dialog(props) {
            let options = {
                title: '生成代码',
                width: 960,
                type: 'close',
            };
            if (props.clazz instanceof EntityClass) {
                Object.assign(options, {
                    type: 'confirm',
                    buttonText: '批量保存代码到文件',
                    click: this.toSubmit,
                });
            }
            return options;
        },
        toSubmit(yes, close) {
            if (yes) {
                let files = [];

                const addFile = function (typeItem, model) {
                    if (model.path) {
                        files.push({
                            type: typeItem.caption,
                            path: model.path,
                            code: model.code,
                        });
                    }
                }

                for (let typeItem of this.typeItems) {
                    let typeName = typeItem.name;
                    if (typeName.startsWith('repo')) {
                        let ref = this.$refs.repo[0];
                        let model = ref.model[typeName];
                        addFile(typeItem, model);
                        for (let subTypeItem of typeItem.subs) {
                            let subModel = ref.generate(subTypeItem.name);
                            addFile(subTypeItem, subModel);
                        }
                    } else if (typeName.startsWith('service')) {
                        let ref = this.$refs.service[0];
                        let model = ref.model[typeName];
                        addFile(typeItem, model);
                        for (let subTypeItem of typeItem.subs) {
                            let subModel = ref.generate(subTypeItem.name);
                            addFile(subTypeItem, subModel);
                        }
                    } else {
                        let ref = this.$refs[typeName][0];
                        let model = ref.model;
                        addFile(typeItem, model);
                        if (typeName === 'jpa') {
                            for (let converterClassName of model.autoConverters) {
                                let converter = ref.generateConverter(converterClassName);
                                if (converter) {
                                    files.push({
                                        type: '枚举类型转换器',
                                        path: converter.path,
                                        code: converter.code,
                                    });
                                }
                            }
                        }
                    }
                }
                tnx.open(save, {
                    app: this.app,
                    files,
                    done(yes) {
                        if (yes) {
                            close();
                        }
                    },
                });
                return false;
            }
        },
    }
}
</script>

<style lang="scss" scoped>
:deep(.el-form) {
    display: flex;
    flex-direction: column;
    height: 450px;

    .code-container {
        height: auto;
    }
}

:deep(.el-tabs__item) {
    padding: 0 1rem !important;
}
</style>
